<template>
  <div class="list-view" ref="listView">
    <div>
      <slot name="upper"></slot>
      <ul class="list">
        <li v-for="group in singers" class="list-group" :key="group.initial" ref="listGroup">
          <slot 
            :title="group.initial" 
            :items="group.page.records" 
            :current="group.page.current" 
            :pages="group.page.pages">
          </slot>
        </li>
      </ul>
    </div>
    <div class="list-shortcut" v-show="shortcutList.length">
      <ul>
        <li v-for="(item, index) in shortcutList"
        class="item"
        :data-index="index"
        :key="item.id"
        @touchstart="onShortcutStart"
        @touchmove.stop.prevent="onShortcutMove"
        :class="{'current': currentIndex === index}"
        >{{ item }}</li>
      </ul>
    </div>
  </div>
</template>

<script>
import BScroll from 'better-scroll'
export default {
  props: {
    shortcutList: {
      type: Array,
      default: () => []
    },
    singers: {
      type: Array,
      default: () => []
    },
    isTrigger: {
      type: Boolean,
      default: false
    }
  },
  data () {
    return {
      scrollY: 0,
      currentIndex: ''
    }
  },
  mounted() {
    this.touch = {}
  },
  methods: {
    _initSrcoll () {
      this.scroll = new BScroll(this.$refs.listView, {
        probeType: 3,
        bounce: false,
        click: true
      })
      this.scroll.on('scroll', (pos) => {
        this.touch.top = this.offsetTop
        this.scrollY = pos.y
      })
    },
    onShortcutStart (e) {
      // 获取到绑定的 index
      let index = e.target.getAttribute('data-index')
      // 使用 better-scroll 的 scrollToElement 方法实现跳转
      this.scrollToElement(index)
      // 记录一下点击时候的 Y坐标 和 index
      let firstTouch = e.touches[0].pageY
      this.touch.y1 = firstTouch
      this.touch.anchorIndex = index
      this.touch.top = 0
    },
    onShortcutMove (e) {
      // 再记录一下移动时候的 Y坐标，然后计算出移动了几个索引
      let touchMove = e.touches[0].pageY
      this.touch.y2 = touchMove
      // 这里的 16.7 是索引元素的高度
      let delta = Math.floor((this.touch.y2 - this.touch.y1) / 16.8)
      // 计算最后的位置
      // * 1 是因为 this.touch.anchorIndex 是字符串，用 * 1 偷懒的转化一下
      let index = this.touch.anchorIndex * 1 + delta
      this.touch.top = 0
      this.scrollToElement(index)
    },
    scrollToElement (index) {
      // 处理边界情况
      // 因为 index 通过滑动距离计算出来的
      // 所以向上滑超过索引框框的时候就会 < 0，向上就会超过最大值
      if (index < 0) {
        return
      } else if (index > this.listHeight.length - 2) {
        index = this.listHeight.length - 2
      }
      // listHeight 是正的， 所以加个 -
      this.scrollY = -this.listHeight[index]
      this.scroll.scrollToElement(this.listGroup[index])
    },
    _calculateHeight () {
      this.listHeight = []
      this.listGroup = this.$refs.listGroup || []
      let height = 0
      this.listHeight.push(height)
      for (let i = 0; i < this.listGroup.length; i++) {
        let item = this.listGroup[i]
        height += item.clientHeight
        this.listHeight.push(height)
      }
    }
  },
  watch: {
    isTrigger(value) {
      // 初始化 better-scroll 必须要等 dom 加载完毕
      setTimeout(() => {
        this._initSrcoll()
        this._calculateHeight()
        this.offsetTop = document.querySelector('.list').offsetTop
      }, 20)
    },
    scrollY (newVal) {
      // 向下滑动的时候 newVal 是一个负数，所以当 newVal > 0 时，currentIndex 直接为 0
      if (newVal > -this.touch.top) {
        this.currentIndex = ''
        return
      }
      if (newVal > 0) {
        this.currentIndex = 0
        return
      }
      // 计算 currentIndex 的值
      for (let i = 0; i < this.listHeight.length - 1; i++) {
        let height1 = this.listHeight[i] + this.touch.top
        let height2 = this.listHeight[i + 1] + this.touch.top
        if (-newVal >= height1 && -newVal < height2) {
          this.currentIndex = i
          return
        }
      }
      // 当超 -newVal > 最后一个高度的时候
      // 因为 this.listHeight 有头尾，所以需要 - 2
      this.currentIndex = this.listHeight.length - 2
    }
  }
}
</script>

<style lang="less">
.list-view {
  position: relative;
  width: 100%;
  height: 100%;
  // height: calc(100% - 56px);
  overflow: hidden;
  background: #F7F9FA;
  .list-group {
    background: #fff;
  }
  .list-shortcut {
    position: absolute;
    z-index: 30;
    right: 0;
    top: 50%;
    transform: translateY(-50%);
    width: 20px;
    padding: 20px 0;
    border-radius: 10px;
    text-align: center;
    // background: rgba(167, 167, 167, 0.5);
    // background: #fff;
    font-family:Helvetica;
    .item {
      padding: 3px;
      line-height: 1;
      color: black;
      font-size: 11px;
      &.current {
        color: #C20C0C;
        // font-weight: bold;
      }
    }
  }
}
</style>